<template>
  <div class="login">
    <div class="login-left">
    </div>
    <div class="login-right">
       <canvas id="tech-canvas"></canvas>
      <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
        <h3 class="title">灵动制联生产执行系统</h3>
        <el-form-item prop="username">
          <el-input
            v-model="loginForm.username"
            type="text"
            auto-complete="off"
            placeholder="账号"
          >
            <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
          </el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input
            v-model="loginForm.password"
            type="password"
            auto-complete="off"
            placeholder="密码"
            @keyup.enter.native="handleLogin"
          >
            <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
          </el-input>
        </el-form-item>
        <el-form-item prop="code" v-if="captchaEnabled">
          <el-input
            v-model="loginForm.code"
            auto-complete="off"
            placeholder="验证码"
            style="width: 63%"
            @keyup.enter.native="handleLogin"
          >
            <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
          </el-input>
          <div class="login-code">
            <img :src="codeUrl" @click="getCode" class="login-code-img"/>
          </div>
        </el-form-item>
        <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
        <el-form-item style="width:100%;">
          <el-button
            :loading="loading"
            size="medium"
            type="primary"
            style="width:100%;"
            @click.native.prevent="handleLogin"
          >
            <span v-if="!loading">登 录</span>
            <span v-else>登 录 中...</span>
          </el-button>
          <div style="float: right;" v-if="register">
            <router-link class="link-type" :to="'/register'">立即注册</router-link>
          </div>
        </el-form-item>
      </el-form>
    </div>
    <!--  底部  -->
    <div class="el-login-footer">
      <!-- <span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span> -->
    </div>
  </div>
</template>

<script>
import { getCodeImg } from "@/api/login"
import Cookies from "js-cookie"
import { encrypt, decrypt } from '@/utils/jsencrypt'

export default {
  name: "Login",
  data() {
    return {
      title: '灵动制联生产执行系统',
      codeUrl: "",
      loginForm: {
        username: "admin",
        password: "admin123",
        rememberMe: false,
        code: "",
        uuid: ""
      },
      loginRules: {
        username: [
          { required: true, trigger: "blur", message: "请输入您的账号" }
        ],
        password: [
          { required: true, trigger: "blur", message: "请输入您的密码" }
        ],
        code: [{ required: true, trigger: "change", message: "请输入验证码" }]
      },
      loading: false,
      // 验证码开关
      captchaEnabled: true,
      // 注册开关
      register: false,
      redirect: undefined
    }
  },
  watch: {
    $route: {
      handler: function(route) {
        this.redirect = route.query && route.query.redirect
      },
      immediate: true
    }
  },
  created() {
    this.getCode()
    this.getCookie()
  },
  mounted() {
    this.initTechCanvas();
  },
  methods: {
    initTechCanvas() {
      const canvas = document.getElementById('tech-canvas');
      const ctx = canvas.getContext('2d');
      const container = canvas.parentElement;

      let stars = [];
      let meteors = [];
      const starCount = 100;
      const meteorCount = 20;

      function resizeCanvas() {
        canvas.width = container.offsetWidth;
        canvas.height = container.offsetHeight;
      }
      
      window.addEventListener('resize', resizeCanvas);
      resizeCanvas();

      class Star {
        constructor() {
          this.x = Math.random() * canvas.width;
          this.y = Math.random() * canvas.height;
          this.radius = Math.random() * 1.5;
          this.alpha = Math.random();
          this.twinkleSpeed = Math.random() * 0.03;
          this.twinkleDirection = 1;
        }
        draw() {
          ctx.save();
          ctx.globalAlpha = this.alpha;
          ctx.fillStyle = 'white';
          ctx.beginPath();
          ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
          ctx.fill();
          ctx.restore();
        }
        update() {
          if (this.alpha >= 1 || this.alpha <= 0) {
            this.twinkleDirection *= -1;
          }
          this.alpha += this.twinkleSpeed * this.twinkleDirection;
          this.draw();
        }
      }

      function drawMoon() {
        const moonX = canvas.width - 100;
        const moonY = 100;
        const moonRadius = 50;
        ctx.save();
        ctx.beginPath();
        ctx.arc(moonX, moonY, moonRadius, 0, Math.PI * 2);
        ctx.fillStyle = 'rgba(240, 240, 240, 0.9)';
        ctx.shadowColor = 'white';
        ctx.shadowBlur = 30;
        ctx.fill();
        ctx.beginPath();
        ctx.arc(moonX - 20, moonY - 10, moonRadius, 0, Math.PI * 2);
        ctx.fillStyle = '#0a0a1a';
        ctx.shadowColor = 'transparent';
        ctx.fill();
        ctx.restore();
      }

      class Meteor {
        constructor() {
          this.reset();
        }

        reset() {
          this.x = Math.random() * canvas.width + 100;
          this.y = -Math.random() * 50;
          this.speed = Math.random() * 4 + 1;
          this.length = Math.random() * 200 + 100;
          this.width = Math.random() * 1.5 + 0.5;
          this.glowColor = 'rgba(173, 216, 230, 0.7)';
        }

        update() {
          this.x -= this.speed;
          this.y += this.speed;
          if (this.x < -this.length || this.y > canvas.height + this.length) {
            this.reset();
          }
        }

        draw() {
          ctx.save();
          
          const gradient = ctx.createLinearGradient(this.x, this.y, this.x - this.length, this.y + this.length);
          gradient.addColorStop(0, 'rgba(64, 158, 255, 0.8)');
          gradient.addColorStop(0.5, 'rgba(64, 158, 255, 0.3)');
          gradient.addColorStop(1, 'transparent');
          
          ctx.strokeStyle = gradient;
          ctx.lineWidth = this.width;
          ctx.beginPath();
          ctx.moveTo(this.x, this.y);
          ctx.lineTo(this.x - this.length, this.y + this.length);
          ctx.stroke();

          ctx.beginPath();
          ctx.arc(this.x - this.length, this.y + this.length, this.width * 1.5, 0, Math.PI * 2);
          ctx.fillStyle = this.glowColor;
          ctx.shadowColor = this.glowColor;
          ctx.shadowBlur = 15;
          ctx.fill();

          ctx.restore();
        }
      }

      for (let i = 0; i < starCount; i++) {
        stars.push(new Star());
      }
      for (let i = 0; i < meteorCount; i++) {
        meteors.push(new Meteor());
      }

      function animate() {
        requestAnimationFrame(animate);
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        drawMoon();
        for (const star of stars) {
          star.update();
        }
        for (const meteor of meteors) {
          meteor.update();
          meteor.draw();
        }
      }

      animate();

      window.addEventListener('resize', () => {
        resizeCanvas();
        stars = [];
        meteors = [];
        for (let i = 0; i < starCount; i++) {
          stars.push(new Star());
        }
        for (let i = 0; i < meteorCount; i++) {
          meteors.push(new Meteor());
        }
      });
    },
    getCode() {
      getCodeImg().then(res => {
        this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled
        if (this.captchaEnabled) {
          this.codeUrl = "data:image/gif;base64," + res.img
          this.loginForm.uuid = res.uuid
        }
      })
    },
    getCookie() {
      const username = Cookies.get("username")
      const password = Cookies.get("password")
      const rememberMe = Cookies.get('rememberMe')
      this.loginForm = {
        username: username === undefined ? this.loginForm.username : username,
        password: password === undefined ? this.loginForm.password : decrypt(password),
        rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
      }
    },
    handleLogin() {
      this.$refs.loginForm.validate(valid => {
        if (valid) {
          this.loading = true
          if (this.loginForm.rememberMe) {
            Cookies.set("username", this.loginForm.username, { expires: 30 })
            Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 })
            Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 })
          } else {
            Cookies.remove("username")
            Cookies.remove("password")
            Cookies.remove('rememberMe')
          }
          this.$store.dispatch("Login", this.loginForm).then(() => {
            this.$router.push({ path: this.redirect || "/" }).catch(()=>{})
          }).catch(() => {
            this.loading = false
            if (this.captchaEnabled) {
              this.getCode()
            }
          })
        }
      })
    }
  }
}
</script>

<style lang="scss">
.login {
  display: flex;
  height: 100vh;
  width: 100vw;
  overflow: hidden;

  .login-left {
    width: 40%;
    background: url('~@/assets/images/image.png') no-repeat center center;
    background-size: contain;
    background-color: #0a0a19;
  }

  .login-right {
    width: 60%;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    background-color: #0a0a1a;

    #tech-canvas {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: 0;
    }

    .login-form {
      border-radius: 6px;
      background: #ffffff;
      width: 400px;
      padding: 25px 25px 5px 25px;
      z-index: 1;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      transition: all 0.3s;
      &:hover {
        box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.2);
      }
      .el-input {
        height: 38px;
        input {
          height: 38px;
        }
      }
      .input-icon {
        height: 39px;
        width: 14px;
        margin-left: 2px;
      }
    }
    .login-code {
      width: 33%;
      height: 38px;
      float: right;
      img {
        cursor: pointer;
        vertical-align: middle;
      }
    }
    .login-code-img {
      height: 38px;
    }
  }
}

.el-login-footer {
  height: 40px;
  line-height: 40px;
  position: fixed;
  bottom: 0;
  width: 100%;
  text-align: center;
  color: #a6a6a6;
  font-family: Arial;
  font-size: 12px;
  letter-spacing: 1px;
}
</style>
